Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MS OAuth - making "/me" API call configurable #93

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

danwritecode
Copy link

Reason for change

When working with Microsoft oauth, you can either pass in MSGraph scopes like: "User.Read" or you can pass in scopes that are needed for your own resources like: "api://resources/Api.Write". However, you cannot pass in both scopes as requesting a singular token for multiple audiences is not possible (noted here and many other places). If you only pass in the scope for your custom resource, you then you get a 401 trying to call the "/me" endpoint (because the user.read scope is missing).

Changes

  1. "useUser" flag added to config
  2. "useUser" default to false (I figured a limited user object is better than error)
  3. if/else block that either fetches from "/me" or decodes the JWT using jwt-decode

Other considerations

  1. I used 3.1.2 of jwt-decode because I was getting some errors with the 4.0 version that I couldn't figure out
  2. It's not possible to type the jwtDecode object as it could be two different JWT formats. I didn't what to hardcode this to the "1.0" version as to be considerate of future changes to this library and the access token used.
  3. I used "displayName" and "mail" as the keys in the user object to match what those keys are in the "/me" response for consistency and to not break any downstream parsing in users app code.

Testing

Within my personal project, I used the module locally and tested with both true/false flags on the useUser configuration key. Everything functioned as I expected it to.

@danwritecode danwritecode requested a review from amandesai01 May 22, 2024 14:58
@danwritecode danwritecode requested a review from amandesai01 May 24, 2024 13:06
@atinux
Copy link
Owner

atinux commented Jun 18, 2024

Sorry for the late review, happy to fix the conflicts?

I would also like another review from @amandesai01

@itpropro
Copy link

Reason for change

When working with Microsoft oauth, you can either pass in MSGraph scopes like: "User.Read" or you can pass in scopes that are needed for your own resources like: "api://resources/Api.Write". However, you cannot pass in both scopes as requesting a singular token for multiple audiences is not possible (noted here and many other places). If you only pass in the scope for your custom resource, you then you get a 401 trying to call the "/me" endpoint (because the user.read scope is missing).

Changes

  1. "useUser" flag added to config
  2. "useUser" default to false (I figured a limited user object is better than error)
  3. if/else block that either fetches from "/me" or decodes the JWT using jwt-decode

Other considerations

  1. I used 3.1.2 of jwt-decode because I was getting some errors with the 4.0 version that I couldn't figure out
  2. It's not possible to type the jwtDecode object as it could be two different JWT formats. I didn't what to hardcode this to the "1.0" version as to be considerate of future changes to this library and the access token used.
  3. I used "displayName" and "mail" as the keys in the user object to match what those keys are in the "/me" response for consistency and to not break any downstream parsing in users app code.

Testing

Within my personal project, I used the module locally and tested with both true/false flags on the useUser configuration key. Everything functioned as I expected it to.

If you request a access_token with a custom scope from Entra ID, it is not possible to query the user info endpoint independent of the scope you provide, as the classic /me endpoint is part of the graph api and you don't have a graph api token anymore.
If you request a access_token for the graph api, you will get an access token for graph api, which is not even a JWT token and thereby not parsable. This is not a token you should ever use in your apis, just in your application for the sake of requesting user information. If you need information about the user, you should adjust the responseType request param to code id_token or id_token. If you have id tokens enabled in Entra ID, you can then add additional user claims to the id_token in the token configuration.
If you need a token to authenticate against your api, you would request a token for your api, which is represented by a separate application registration in Entra ID. The id of that api app should be announced by adding the resource field to the code request and is represented by the audience field in the response access token. This token must be validated by your api and first checked if the apis id is in the audience claim and then the signature has to be verified.
If one of these fails, the token needs to be rejected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants